package damuzee.ge;

import java.io.File;
import java.io.FileOutputStream;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import freemarker.template.Template;


public class Cms {
	
	public static String basePath  = "E:/workspace/weixin/damuzee-web/src/main/java/";
	
	public static String tableSchema = "shop" ;
	
	public static void main(String[] args) {
		Cms codeGe =new Cms();

		String basePackage  = "com.damuzee" ;
        String moduleName = "cms";
		String packageName = "model" ;
		String [] tables = {"cms_field_type"} ;
		String template [] =  {"bean::java:domain","mapper:Mapper:java:persistence","xml:Maper:xml:persistence","service:I,Service:java:service","serviceimp:ServiceImpl:java:service"};
		
		codeGe.generate(basePackage,moduleName,packageName,tables,template);
	}
	
	public void generate(String basePackage ,String moduleName,String packageName,String [] tables,String template [] ){
		ApplicationContext cxt = new ClassPathXmlApplicationContext("ge.xml");
		SqlSessionFactory sessionFactory = (SqlSessionFactory) cxt.getBean("sqlSessionFactory");
		FreeMarkerConfigurer freeMarkerConfigurer  = (FreeMarkerConfigurer)cxt.getBean("freemarkerConfig");
		try {
			SqlSession session = sessionFactory.openSession();
			Connection conn = session.getConnection();
			DatabaseMetaData metaData = conn.getMetaData();
			
			//获取表
			//	ResultSet rs = metaData.getTables(conn.getCatalog(), null, null, new String[]{"TABLE"});
			//while(rs.next()) {
			
			if(tables!=null)
			for (String tableName:tables){
				Map<String, Object> map = new HashMap<String, Object>();
				
			 //  String tableName =  rs.getString("TABLE_NAME");
			   List list = getCommentByTableName(conn,tableName);
			   
			   String beanName =getClassName(tableName);
			   map.put("basePackage", basePackage);
			   map.put("tableName", tableName);
			   map.put("beanName", beanName);
			   map.put("nickName", toUpcaseByIndex(beanName,0));
			   map.put("column", list);
                map.put("moduleName",moduleName);
			   map.put("packageName", packageName);
			   
			   if(beanName.length()==0){
				   return;
			   }
			   for(String t :template){
				   	String temp [] = t.split(":");
				   String ftlpath = "template/"+temp[0] + ".ftl" ;
				   Template tpl = freeMarkerConfigurer.getConfiguration().getTemplate(ftlpath );
					// 解析模板并替换动态数据，最终username将替换模板文件中的${username}标签。
					String text = FreeMarkerTemplateUtils.processTemplateIntoString(tpl, map);
					String filePath = null;
					if(temp[0].endsWith("imp")){
						filePath = basePath +basePackage.replaceAll("\\.","/") +"/" + moduleName +"/" + packageName+"/"+temp[3]+"/impl/" ;
					}else{
					  filePath = basePath + basePackage.replaceAll("\\.","/") +"/" + moduleName +"/"+ packageName+"/"+temp[3]+"/"  ;
					}
					System.out.println(filePath);
					File file= new File(filePath);
					if(!file.exists()){
						file.mkdirs();
					}
					FileOutputStream fos  = null ;
					String temp1 = temp[1];
					if (temp1.contains(",")) {
						String nick []  = temp1.split(",");
						  fos = new FileOutputStream(filePath+nick[0] + beanName +nick[1]+"." + temp[2]);
					}else{
						  fos = new FileOutputStream(filePath+beanName +temp[1]+"." + temp[2]);
					}
					 
					fos.write(text.getBytes());
					
					fos.flush(); 
					fos.close(); 
			   }
			}
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	public String toUpcaseByIndex(String str ,Integer idx){
		char [] c = str.toCharArray();
		c[idx] = Character.toLowerCase(c[idx]);
		return new String(c);
	}
	public List getCommentByTableName(Connection conn ,String tableName) throws Exception {
       
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM information_schema.columns WHERE TABLE_SCHEMA = 'shop' and  table_name ='" + tableName  + "'");
        System.out.println("-------------tableName   " + tableName + "  :----------------------------");
        List list  =new ArrayList();
        while (rs.next()) {
        	Map map = new HashMap();
        	String columnName = rs.getString("column_name");
     	   	String columnType = rs.getString("DATA_TYPE");
     	   	Long datasize = rs.getLong("CHARACTER_MAXIMUM_LENGTH");
     	   	//int digits = rs.getInt("DECIMAL_DIGITS");
     	   	boolean nullable = rs.getBoolean("IS_NULLABLE");  
     	   	String  remarks = rs.getString("COLUMN_COMMENT");
     	   	String defaultStr = rs.getString("COLUMN_DEFAULT");
     		String pri = rs.getString("COLUMN_KEY");
     		
     		
     		map.put("prikey", pri.equals("PRI"));
     	   	map.put("columnName", columnName);
     	 
     	   	map.put("fieldName", getFiledName(columnName));
     		map.put("fieldMethod", getFiledMethod(columnName));
     	   	map.put("type", getType(columnType));
     	   	
     	   	map.put("nullable", nullable);
     	   	map.put("length", datasize);
     	   	map.put("remarks", remarks);

            System.out.println(" 列名：" + getFiledName(columnName) + " 类型： " + getType(columnType) + "是否主键：" + pri.equals("PRI"));
     	   	list.add(map);
		}
   
        return list;
	}
	
	public String getClassName(String name){
		return getName(name,3,'_',true);
	}
	
	public String getFiledName(String name){
		return getName(name,3,'_',false);
	}
	
	public String getFiledMethod(String name){
		String field  =getName(name,3,'_',false) ;
		char [] c = field.toCharArray();
		c[0] = Character.toUpperCase(c[0]);
		return new String(c);
	}
	
	//数据类型转换
	public String  getType(String type ){
		Hashtable<String,String> ht_columnType=new Hashtable<String,String>();
		ht_columnType.put("char","String");
		ht_columnType.put("varchar","String");
		ht_columnType.put("datetime","Date");	
		ht_columnType.put("date", "Date");
		ht_columnType.put("int","Integer");	
		ht_columnType.put("bigint","Long");	
		ht_columnType.put("bit","boolean");		
		ht_columnType.put("decimal","Double");
		ht_columnType.put("longtext", "String");
		ht_columnType.put("float", "Float");
		
		return ht_columnType.get(type.toLowerCase());
	}
	
	//生成c
	public String getName(String name,int startIndex,char splite,boolean flag){
		
		char [] oc = name.toCharArray() ;
		
		char [] nc = new char[oc.length];
		int j = 0 ;
		boolean temp =false;
		int i = name.indexOf(splite) !=-1 && flag ? startIndex:0 ;
		for (; i < oc.length; i++) {
			if(oc[i] == splite){
				temp = true ;
				continue ;
			}
			if(temp){
				nc[j] = Character.toUpperCase(oc[i]) ;
			}else{
				nc[j] = oc[i];
			}
			temp =false ;
			j++ ;	
		}
		
		if (flag) {
			nc[0] = Character.toUpperCase(nc[0]) ;
		}
		name = new String(nc);
		return  name.trim();
	}
	
}
